package com.cxy.hmall.db.service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import com.cxy.hmall.db.dao.HCouponMapper;
import com.cxy.hmall.db.dao.HCouponUserMapper;
import com.cxy.hmall.db.domain.HCoupon;
import com.cxy.hmall.db.domain.HCouponExample;
import com.cxy.hmall.db.domain.HCouponUser;
import com.cxy.hmall.db.domain.HCouponUserExample;
import com.cxy.hmall.db.util.CouponConstant;
import org.springframework.stereotype.Service;

import com.alibaba.druid.util.StringUtils;
import com.github.pagehelper.PageHelper;

@Service
public class HCouponService {
	@Resource
	private HCouponMapper couponMapper;
	@Resource
	private HCouponUserMapper couponUserMapper;

	private HCoupon.Column[] result = new HCoupon.Column[] { HCoupon.Column.id, HCoupon.Column.name, HCoupon.Column.desc, HCoupon.Column.tag, HCoupon.Column.days,
			HCoupon.Column.startTime, HCoupon.Column.endTime, HCoupon.Column.discount, HCoupon.Column.min };

	/**
	 * 查询，空参数
	 *
	 * @param offset
	 * @param limit
	 * @param sort
	 * @param order
	 * @return
	 */
	public List<HCoupon> queryList(int offset, int limit, String sort, String order) {
		return queryList(HCouponExample.newAndCreateCriteria(), offset, limit, sort, order);
	}

	/**
	 * 查询
	 *
	 * @param criteria
	 *            可扩展的条件
	 * @param offset
	 * @param limit
	 * @param sort
	 * @param order
	 * @return
	 */
	public List<HCoupon> queryList(HCouponExample.Criteria criteria, int offset, int limit, String sort,
								   String order) {
		criteria.andTypeEqualTo(CouponConstant.TYPE_COMMON).andStatusEqualTo(CouponConstant.STATUS_NORMAL)
				.andDeletedEqualTo(false);
		criteria.example().setOrderByClause(sort + " " + order);
		PageHelper.startPage(offset, limit);
		return couponMapper.selectByExampleSelective(criteria.example(), result);
	}

	public int queryTotal() {
		HCouponExample example = new HCouponExample();
		example.or().andTypeEqualTo(CouponConstant.TYPE_COMMON).andStatusEqualTo(CouponConstant.STATUS_NORMAL)
				.andDeletedEqualTo(false);
		return (int) couponMapper.countByExample(example);
	}

	public List<HCoupon> queryAvailableList(Integer userId, int offset, int limit) {
		assert userId != null;
		// 过滤掉登录账号已经领取过的coupon
		HCouponExample.Criteria c = HCouponExample.newAndCreateCriteria();
		List<HCouponUser> used = couponUserMapper
				.selectByExample(HCouponUserExample.newAndCreateCriteria().andUserIdEqualTo(userId).example());
		if (used != null && !used.isEmpty()) {
			c.andIdNotIn(used.stream().map(HCouponUser::getCouponId).collect(Collectors.toList()));
		}
		return queryList(c, offset, limit, "add_time", "desc");
	}

	public List<HCoupon> queryList(int offset, int limit) {
		return queryList(offset, limit, "add_time", "desc");
	}

	public HCoupon findById(Integer id) {
		return couponMapper.selectByPrimaryKey(id);
	}

	public HCoupon findByCode(String code) {
		HCouponExample example = new HCouponExample();
		example.or().andCodeEqualTo(code).andTypeEqualTo(CouponConstant.TYPE_CODE)
				.andStatusEqualTo(CouponConstant.STATUS_NORMAL).andDeletedEqualTo(false);
		List<HCoupon> couponList = couponMapper.selectByExample(example);
		if (couponList.size() > 1) {
			throw new RuntimeException("");
		} else if (couponList.size() == 0) {
			return null;
		} else {
			return couponList.get(0);
		}
	}

	/**
	 * 查询新用户注册优惠券
	 *
	 * @return
	 */
	public List<HCoupon> queryRegister() {
		HCouponExample example = new HCouponExample();
		example.or().andTypeEqualTo(CouponConstant.TYPE_REGISTER).andStatusEqualTo(CouponConstant.STATUS_NORMAL)
				.andDeletedEqualTo(false);
		return couponMapper.selectByExample(example);
	}

	public List<HCoupon> querySelective(String name, Short type, Short status, Integer page, Integer limit,
                                        String sort, String order) {
		HCouponExample example = new HCouponExample();
		HCouponExample.Criteria criteria = example.createCriteria();

		if (!StringUtils.isEmpty(name)) {
			criteria.andNameLike("%" + name + "%");
		}
		if (type != null) {
			criteria.andTypeEqualTo(type);
		}
		if (status != null) {
			criteria.andStatusEqualTo(status);
		}
		criteria.andDeletedEqualTo(false);

		if (!StringUtils.isEmpty(sort) && !StringUtils.isEmpty(order)) {
			example.setOrderByClause(sort + " " + order);
		}

		PageHelper.startPage(page, limit);
		return couponMapper.selectByExample(example);
	}

	public void add(HCoupon coupon) {
		coupon.setAddTime(LocalDateTime.now());
		coupon.setUpdateTime(LocalDateTime.now());
		couponMapper.insertSelective(coupon);
	}

	public int updateById(HCoupon coupon) {
		coupon.setUpdateTime(LocalDateTime.now());
		return couponMapper.updateByPrimaryKeySelective(coupon);
	}

	public void deleteById(Integer id) {
		couponMapper.logicalDeleteByPrimaryKey(id);
	}

	private String getRandomNum(Integer num) {
		String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		base += "0123456789";

		Random random = new Random();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < num; i++) {
			int number = random.nextInt(base.length());
			sb.append(base.charAt(number));
		}
		return sb.toString();
	}

	/**
	 * 生成优惠码
	 *
	 * @return 可使用优惠码
	 */
	public String generateCode() {
		String code = getRandomNum(8);
		while (findByCode(code) != null) {
			code = getRandomNum(8);
		}
		return code;
	}

	/**
	 * 查询过期的优惠券: 注意：如果timeType=0, 即基于领取时间有效期的优惠券，则优惠券不会过期
	 *
	 * @return
	 */
	public List<HCoupon> queryExpired() {
		HCouponExample example = new HCouponExample();
		example.or().andStatusEqualTo(CouponConstant.STATUS_NORMAL).andTimeTypeEqualTo(CouponConstant.TIME_TYPE_TIME)
				.andEndTimeLessThan(LocalDate.now()).andDeletedEqualTo(false);
		return couponMapper.selectByExample(example);
	}
}
